package com.spark.gaea.utils;

import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public final class DateUtil {
	private static final Logger LOG;
	public static final String YMDHMS = "yyyy-MM-dd HH:mm:ss";
	public static final String YMDHM = "yyyy-MM-dd HH:mm";
	public static final String YMDH = "yyyy-MM-dd HH";
	public static final String YMD = "yyyy-MM-dd";
	public static final String HMS = "HH:mm:ss";
	public static final String CH_YMDHMS = "yyyy\u5e74MM\u6708dd\u65e5 HH:mm:ss";
	public static final String CH_YMDHM = "yyyy\u5e74MM\u6708dd\u65e5 HH:mm";
	public static final String CH_YMDH = "yyyy\u5e74MM\u6708dd\u65e5 HH";
	public static final String CH_YMD = "yyyy\u5e74MM\u6708dd\u65e5";
	private static Date date;
	private static String[] dates;
	private static SimpleDateFormat sdf;
	private static ThreadLocal<SimpleDateFormat> DF_TL;

	public static String get(final String format) {
		return format(format);
	}

	public static String format(final Date date) {
		return format(date, "yyyy-MM-dd HH:mm:ss");
	}

	public static String format(final String format) {
		return format(new Date(), format);
	}

	public static String format(final Date date, final String format) {
		if (date == null) {
			return "";
		}
		final SimpleDateFormat formater = DateUtil.DF_TL.get();
		formater.setLenient(false);
		formater.applyPattern(format);
		return formater.format(date);
	}

	public static Date parse(final String string) {
		try {
			return DateUtils.parseDateStrictly(string, Locale.CHINA, "yyyy-MM-dd HH:mm:ss",
					"yyyy\u5e74MM\u6708dd\u65e5 HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy\u5e74MM\u6708dd\u65e5 HH:mm",
					"yyyy-MM-dd HH", "yyyy\u5e74MM\u6708dd\u65e5 HH", "yyyy-MM-dd", "yyyy\u5e74MM\u6708dd\u65e5",
					"HH:mm:ss");
		} catch (ParseException e) {
			DateUtil.LOG.warn("解析日期时出现了错误：" + string);
			return null;
		}
	}

	public static Date parse(final String string, final String format) {
		try {
			final SimpleDateFormat formater = DateUtil.DF_TL.get();
			formater.setLenient(false);
			formater.applyPattern(format);
			return formater.parse(string);
		} catch (ParseException e) {
			DateUtil.LOG.warn("解析日期时出现了错误：" + string);
			return null;
		}
	}

	public static Date timestamp2Date(final String string) {
		return new Date(Long.parseLong(string) * 1000L);
	}

	public static Date getDate() {
		return DateUtil.date;
	}

	public static String getTime() {
		final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		final Date dNow = new Date();
		final String nDate = sdf.format(dNow);
		return nDate;
	}

	public static String getStringDateCHN(String date) {
		DateUtil.dates = new String[3];
		if (date.split(" ").length > 1) {
			DateUtil.dates = date.split(" ");
			date = DateUtil.dates[0];
		}
		if (date.length() < 11) {
			DateUtil.dates = dateSplit(date);
			if (DateUtil.dates[0].length() < 2 && DateUtil.dates[1].length() == 2) {
				DateUtil.dates[1] = "0" + DateUtil.dates[1];
			} else if (DateUtil.dates[0].length() == 2 && DateUtil.dates[1].length() < 2) {
				DateUtil.dates[2] = "0" + DateUtil.dates[2];
			} else if (DateUtil.dates[0].length() < 2 && DateUtil.dates[1].length() < 2) {
				DateUtil.dates[0] = "0" + DateUtil.dates[0];
				DateUtil.dates[1] = "0" + DateUtil.dates[1];
			}
			return DateUtil.dates[0] + "\u5e74" + DateUtil.dates[1] + "\u6708" + DateUtil.dates[2] + "\u65e5";
		}
		DateUtil.dates = dateSplit(date);
		return DateUtil.dates[0] + "\u5e74" + DateUtil.dates[1] + "\u6708" + DateUtil.dates[2] + "\u65e5";
	}

	private static final String[] dateSplit(final String date) {
		DateUtil.dates = new String[3];
		final Character character = date.charAt(4);
		if (character.toString().equals("\u5e74")) {
			final String[] dates1 = date.split("\u5e74");
			final String[] dates2 = dates1[1].split("\u6708");
			final String[] dates3 = dates2[1].split("\u65e5");
			DateUtil.dates[0] = dates1[0];
			DateUtil.dates[1] = dates2[0];
			DateUtil.dates[2] = dates3[0];
			return DateUtil.dates;
		}
		return DateUtil.dates = date.split(character.toString());
	}

	private static final String[] dateSplitReverse(final String date) {
		DateUtil.dates = new String[3];
		Character character = ' ';
		if (date.length() < 10) {
			character = date.charAt(1);
		} else if (date.length() < 11) {
			character = date.charAt(1);
		} else {
			character = date.charAt(2);
		}
		if (character.toString().equals("\u5e74")) {
			final String[] dates1 = date.split("\u5e74");
			final String[] dates2 = dates1[1].split("\u6708");
			final String[] dates3 = dates2[1].split("\u65e5");
			DateUtil.dates[0] = dates1[0];
			DateUtil.dates[1] = dates2[0];
			DateUtil.dates[2] = dates3[0];
			return DateUtil.dates;
		}
		return DateUtil.dates = date.split(character.toString());
	}

	private static final String[] timeSplit(final String time) {
		final Character character = time.charAt(2);
		return time.split(character.toString());
	}

	public static int getDateDifference(final Date date1, final Date date2) {
		final Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date1);
		final Calendar cal2 = Calendar.getInstance();
		cal2.setTime(date2);
		final int day1 = cal1.get(6);
		final int day2 = cal2.get(6);
		final int year1 = cal1.get(1);
		final int year2 = cal2.get(1);
		if (year1 == year2) {
			return day2 - day1;
		}
		if (year1 < year2) {
			int timeDistance = 0;
			for (int i = year1; i < year2; ++i) {
				if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {
					timeDistance += 366;
				} else {
					timeDistance += 365;
				}
			}
			return timeDistance + (day2 - day1);
		}
		if (year1 > year2) {
			int timeDistance = 0;
			for (int i = year2; i < year1; ++i) {
				if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {
					timeDistance -= 366;
				} else {
					timeDistance -= 365;
				}
			}
			return timeDistance + (day2 - day1);
		}
		return 0;
	}

	static {
		LOG = LoggerFactory.getLogger(DateUtil.class);
		DateUtil.date = new Date();
		DateUtil.dates = null;
		DateUtil.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		DateUtil.DF_TL = new ThreadLocal<SimpleDateFormat>() {
			@Override
			protected synchronized SimpleDateFormat initialValue() {
				return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
			}
		};
	}
}
